package person.wend.javalearnexample.util;

import java.util.List;
import java.util.Random;
import java.util.SplittableRandom;
import java.util.concurrent.ThreadLocalRandom;
import java.util.stream.*;

public class RandomExample {
    public static void main(String[] args) {
        setSeedTest();
        nextTest();
        streamTest();
        SplittableRandomtTest();
        threadLocalRandomTest();
    }

    public static void threadLocalRandomTest(){
        // 生成一个随机整数
        int randomInt = ThreadLocalRandom.current().nextInt();
        System.out.println("Random Integer: " + randomInt);

        // 生成一个指定范围内的随机整数
        int randomIntWithinRange = ThreadLocalRandom.current().nextInt(10, 20);
        System.out.println("Random Integer within range 10-20: " + randomIntWithinRange);

        // 生成一个随机浮点数
        double randomDouble = ThreadLocalRandom.current().nextDouble();
        System.out.println("Random Double: " + randomDouble);

        // 生成一个随机布尔值
        boolean randomBoolean = ThreadLocalRandom.current().nextBoolean();
        System.out.println("Random Boolean: " + randomBoolean);
    }

    public static void SplittableRandomtTest() {
        // 生成一个SplittableRandom对象
        SplittableRandom random = new SplittableRandom();
        SplittableRandom seededRandom = new SplittableRandom(12345L);


        int randomInt = random.nextInt();
        int boundedInt = random.nextInt(100); // 0 到 99 之间的随机数
        long randomLong = random.nextLong();
        double randomDouble = random.nextDouble();
        boolean randomBoolean = random.nextBoolean();
        // SplittableRandom split(): 创建并返回一个新的 SplittableRandom 实例，它与当前实例独立，但具有相同的随机性特征。
        SplittableRandom splitRandom = random.split();
        double gaussian = splitRandom.nextGaussian();

        SplittableRandom splittableRandom = new SplittableRandom();

        // 使用并行流生成 10 个随机数
        List<Integer> randomNumbers = Stream.generate(splittableRandom::nextInt)
                .limit(10)
                .parallel()
                .collect(Collectors.toList());

        System.out.println(randomNumbers);

    }

    public static void setSeedTest() {
        Random random = new Random();
        // 初始生成一个随机整数
        int num1 = random.nextInt();
        System.out.println("初始随机整数: " + num1);

        // 设置新的种子
        random.setSeed(54321L);
        // 再次生成随机整数
        int num2 = random.nextInt();
        System.out.println("设置种子后生成的随机整数: " + num2);
    }

    public static void streamTest() {
        Random random = new Random();

        // 生成10个伪随机int值的流并打印
        IntStream intStream = random.ints(10);
        intStream.forEach(System.out::println);

        // 生成无限个伪随机int值的流，取前5个打印（限制操作）
        IntStream infiniteIntStream = random.ints();
        infiniteIntStream.limit(5).forEach(System.out::println);

        // 生成10个指定范围（5到15，不包含15）的伪随机int值的流并打印
        IntStream rangedIntStream = random.ints(10, 5, 15);
        rangedIntStream.forEach(System.out::println);

        // 生成10个伪随机long值的流并打印
        LongStream longStream = random.longs(10);
        longStream.forEach(System.out::println);

        // 生成无限个伪随机long值的流，取前5个打印（限制操作）
        LongStream infiniteLongStream = random.longs();
        infiniteLongStream.limit(5).forEach(System.out::println);

        // 生成10个指定范围（10L到20L，不包含20L）的伪随机long值的流并打印
        LongStream rangedLongStream = random.longs(10, 10L, 20L);
        rangedLongStream.forEach(System.out::println);

        // 生成10个伪随机double值（0到1之间）的流并打印
        DoubleStream doubleStream = random.doubles(10);
        doubleStream.forEach(System.out::println);

        // 生成无限个伪随机double值的流，取前5个打印（限制操作）
        DoubleStream infiniteDoubleStream = random.doubles();
        infiniteDoubleStream.limit(5).forEach(System.out::println);

        // 生成10个指定范围（0.5到1.5，不包含1.5）的伪随机double值的流并打印
        DoubleStream rangedDoubleStream = random.doubles(10, 0.5, 1.5);
        rangedDoubleStream.forEach(System.out::println);
    }

    public static void nextTest() {
        Random random = new Random();

        // 生成随机字节数组
        byte[] bytes = new byte[5];
        random.nextBytes(bytes);
        for (byte b : bytes) {
            System.out.print(b + " ");
        }
        System.out.println();

        // 生成随机int值
        int randomInt = random.nextInt();
        System.out.println("随机int值: " + randomInt);

        // 生成指定范围的随机int值（0到100，不包含100）
        int boundedRandomInt = random.nextInt(100);
        System.out.println("指定范围的随机int值: " + boundedRandomInt);

        // 生成随机long值
        long randomLong = random.nextLong();
        System.out.println("随机long值: " + randomLong);

        // 生成随机boolean值
        boolean randomBoolean = random.nextBoolean();
        System.out.println("随机boolean值: " + randomBoolean);

        // 生成随机float值（0到1之间）
        float randomFloat = random.nextFloat();
        System.out.println("随机float值: " + randomFloat);

        // 生成随机double值（0到1之间）
        double randomDouble = random.nextDouble();
        System.out.println("随机double值: " + randomDouble);

        // 生成符合高斯分布的随机double值
        double gaussianRandomDouble = random.nextGaussian();
        System.out.println("符合高斯分布的随机double值: " + gaussianRandomDouble);
    }
}
